package com.yamibuy.ec.resource.domain;

import cn.hutool.core.codec.Base64;
import com.yamibuy.ec.resource.aws.AwsUrlDecode;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 图片规则
 *
 * @author: damon.li
 * @version: 2021年02月23日 9:39
 */
@Data
@Slf4j
public class ImageRule {

	/**
	 * 正则匹配文件规则
	 */
	private static final Pattern filePattern = Pattern.compile("(/.+)+(/[^./]+)+\\.?(jpg|png|webp|tiff|jpeg|bmp)?(\\?.+)?");

	/**
	 * 水印文件识别
	 */
	private static final Pattern waterPattern = Pattern.compile("([^_.]+)+(_watermark)?(_h\\d+)?(_i\\d+)?(_\\d+x\\d+)?");

	/**
	 * 0
	 * 阿里云的图片处理规则识别
	 */
	private static final Pattern aliOssRegs = Pattern.compile("\\?x-oss-process=image/format,(.+)/resize,(.+),(.+)/watermark,image_(.+),(.+),(.+),(.+)");

	/**
	 * 阿里云水印规则
	 */
	private static final Pattern aliWaterRegs = Pattern.compile("(.+)\\?x-oss-process=image\\/resize,P_(\\d+)");

	private String fullPath;

	private String folderPath;

	private String md5Path;

	private Integer width;

	private Integer height;

	private Integer extractHeight;

	private Integer extractPage;

	private String fileType;

	private WatermarkRule watermarkRule;

	public ImageRule(String requestKeyRule) {
		log.debug("图片规则解析: {}", requestKeyRule);
		this.fullPath = requestKeyRule;
		Matcher matcher = filePattern.matcher(requestKeyRule);
		if (matcher.find()) {
			String folderPath = matcher.group(1);
			String fileType = matcher.group(3);
			this.folderPath = folderPath.substring(1, folderPath.length());
			this.fileType = fileType;
			// 文件名匹配
			String fileNameRule = matcher.group(2);
			Matcher waterMatch = waterPattern.matcher(fileNameRule);
			if (waterMatch.find()) {
				// 文件名
				this.md5Path = waterMatch.group(1);
				if(this.md5Path == null || !this.md5Path.matches("/\\w{32}")){
					// 非图片处理规则，原图方式尝试
					int lastIndex = requestKeyRule.lastIndexOf("/");
					this.folderPath = requestKeyRule.substring(1, lastIndex);
					this.md5Path = requestKeyRule.substring(lastIndex, requestKeyRule.length());
				}
				// 图片缩放宽高
				handleWidthHeight(waterMatch.group(5));
				// 默认水印
				String waterMatchMark = waterMatch.group(2);
				if (waterMatchMark != null) {
					WatermarkRule watermarkRule = new WatermarkRule();
					this.watermarkRule = watermarkRule;
				}
				// 裁剪
				String cutArea = waterMatch.group(3);
				if (cutArea != null) {
					this.extractHeight = Integer.valueOf(cutArea.replace("_h", ""));
				}
				// 裁剪取第几个图片
				String cutNum = waterMatch.group(4);
				if (cutNum != null) {
					this.extractPage = Integer.valueOf(cutNum.replace("_i", ""));
				}
			}

			// 阿里云规则，可以覆盖亚米规则
			String aliossRule = matcher.group(4);
			if (aliossRule != null) {
				handleAliRule(aliossRule);
			}
		}
	}

	/**
	 * 处理阿里云规则
	 *
	 * @param aliossRule
	 */
	private void handleAliRule(String aliossRule) {

		// 1.文件格式 2宽度 3高度 4水印base64 5水印位置 6水印x位置 7水印y位置
		Matcher matcher = aliOssRegs.matcher(aliossRule);
		if (!matcher.find()) {
			return;
		}

		// 文件类型
		fileType = matcher.group(1);

		// 宽度
		String group2 = matcher.group(2);
		if (group2 != null) {
			width = Integer.valueOf(group2.replace("w_", ""));
		}

		// 高度
		String group3 = matcher.group(3);
		if (group3 != null) {
			height = Integer.valueOf(group3.replace("h_", ""));
		}

		// 水印图
		String position = matcher.group(5);
		if (position != null) {
			WatermarkRule watermarkRule = new WatermarkRule();
			String watermarkKeyRuleBase64 = matcher.group(4);
			String watermarkKeyRule = Base64.decodeStr(watermarkKeyRuleBase64);
			Matcher matcherWater = aliWaterRegs.matcher(watermarkKeyRule);
			if (matcherWater.find()) {
				watermarkRule.setKey(matcherWater.group(1));
				watermarkRule.setWidth(Integer.valueOf(matcherWater.group(2)));
				watermarkRule.setHeight(Integer.valueOf(matcherWater.group(2)));
			}

			if ("g_nw".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.TOP_LEFT);
			}
			if ("g_north".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.TOP_CENTER);
			}
			if ("g_ne".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.TOP_RIGHT);
			}
			if ("g_west".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.CENTER_LEFT);
			}
			if ("g_center".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.CENTER);
			}
			if ("g_east".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.CENTER_RIGHT);
			}
			if ("g_sw".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.BOTTOM_LEFT);
			}
			if ("g_south".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.BOTTOM_CENTER);
			}
			if ("g_se".equals(position)) {
				watermarkRule.setWaterPositions(WaterPositions.BOTTOM_RIGHT);
			}


			this.watermarkRule = watermarkRule;
		}
	}

	/**
	 * 获取文件的Key
	 *
	 * @return
	 */
	public String getFileKey() {
		String fileKey = this.folderPath + this.md5Path;
		fileKey = AwsUrlDecode.decode(fileKey);
		return fileKey;
	}

	/**
	 * 是否需要处理高度宽度
	 *
	 * @return
	 */
	public boolean needHandleWidthHeight() {
		return this.width != null && this.height != null;
	}

	/**
	 * 是否裁剪
	 *
	 * @return
	 */
	public boolean needHandleCut() {
		return this.extractHeight != null && this.extractPage != null;
	}

	/**
	 * 是否需要处理
	 *
	 * @return
	 */
	public boolean needHandle() {
		return this.width != null || this.height != null || watermarkRule != null || extractHeight != null;
	}

	/**
	 * 图片缩放宽高处理
	 *
	 * @param widthHeightRule
	 */
	private void handleWidthHeight(String widthHeightRule) {
		log.debug("宽高解析: {}", widthHeightRule);
		if (widthHeightRule != null) {
			String[] widthHeight = widthHeightRule.replace("_", "").split("x");
			if (!widthHeight[0].equals("0") && !widthHeight[1].equals("0")) {
				this.width = Integer.valueOf(widthHeight[0]);
				this.height = Integer.valueOf(widthHeight[1]);
			}
		}
	}
}
